/*
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package eu.fastl.dragster.util;

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import org.apache.commons.lang.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UrlUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(UrlUtils.class);
    public static final String DEFAULT_ENCODING = "UTF-8";
    public static final String PARAMETER_SEPARATOR = "&";
    public static final String NAME_VALUE_SEPARATOR = "=";

    public static boolean isValidUrl(String url) {
        if (StringUtils.isBlank(url))
            return false;
        try {
            URI.create(url);
            new URL(url);
        } catch (Exception e) {
            LOGGER.debug("Invalid URL:" + url, e);
            return false;
        }
        return true;
    }

    public static String encodeParameters(String url) {
        String requestUri = StringUtils.substringBefore(url, "?");
        String queryString = StringUtils.substringAfter(url, "?");
        List<NameValuePair> parameters = new ArrayList<NameValuePair>();
        UrlUtils.parse(parameters, new Scanner(queryString), UrlUtils.DEFAULT_ENCODING);
        String encodedQueryString = URLEncodedUtils.format(parameters, UrlUtils.DEFAULT_ENCODING);
        return requestUri + "?" + encodedQueryString;
    }

    /**
     * Special Parameter parsing method which allows the special parameter
     * format &key=value,subkey=subvalue&
     *
     * @param parameters
     *            the List to which the parameters will be saved to
     * @param scanner
     *            a Scanner of the String
     * @param encoding
     *            the Encoding to use
     */
    public static void parse(final List<NameValuePair> parameters, final Scanner scanner, final String encoding) {
        scanner.useDelimiter(UrlUtils.PARAMETER_SEPARATOR);
        while (scanner.hasNext()) {
            final String nameValuePair = scanner.next();
            if (nameValuePair.contains(UrlUtils.NAME_VALUE_SEPARATOR)) {
                final String encodedName = StringUtils.substringBefore(nameValuePair, UrlUtils.NAME_VALUE_SEPARATOR);
                final String encodedValue = StringUtils.substringAfter(nameValuePair, UrlUtils.NAME_VALUE_SEPARATOR);

                final String name = UrlUtils.decode(encodedName, encoding);
                final String value = UrlUtils.decode(encodedValue, encoding);

                parameters.add(new BasicNameValuePair(name, value));
            } else {
                final String parameter = UrlUtils.decode(nameValuePair, encoding);
                parameters.add(new BasicNameValuePair(parameter, null));
            }
        }
    }

    public static String decode(final String content, final String encoding) {
        try {
            return URLDecoder.decode(content, encoding != null ? encoding : "UTF-8");
        } catch (UnsupportedEncodingException problem) {
            throw new IllegalArgumentException(problem);
        } catch (IllegalArgumentException e) {
            LOGGER.warn("Could not decode String " + content, e);
            return content;
        }
    }

}
